import datetime
import json
import time
from hashlib import sha256


class Block(object):

    def __init__(
            self, index=0, nonce=0, previous_hash=None, data=None, hash=None,
            timestamp=None, create_time=None, gas_fee=None, node=1):
        self.index = index
        self.previous_hash = previous_hash or '0'
        self.timestamp = timestamp or time.time()
        self.data = data or ''
        self.nonce = nonce
        self.hash = hash or self._calculate_hash()
        self.create_time = create_time or datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        self.gas_fee = gas_fee or ''
        self.node = node or 1

    def to_dict(self):
        return {
            'index': self.index,
            'previous_hash': self.previous_hash,
            'timestamp': self.timestamp,
            'data': self.data,
            'nonce': self.nonce,
            'hash': self.hash,
            'create_time': self.create_time,
            'gas_fee': self.gas_fee,
            'node': self.node
        }

    @staticmethod
    def genesis():
        return Block(
            0, 0, '0', {'content': 'first crowdfunding blockchain!', 'user_id': 0, 'task_id': 0, 'extra': {}},
            '8724f78170aee146b794ca6ad451d23c254717727e18e2b9643b81d5666aa908',
            1520572079.336289)

    def _calculate_hash(self):
        original_str = ''.join([
            str(self.index), self.previous_hash, str(self.timestamp), str(self.data),
            str(self.nonce)])
        return sha256(original_str.encode('utf-8')).hexdigest()

    def __eq__(self, other):
        if (self.index == other.index
                and self.previous_hash == other.previous_hash
                and self.timestamp == other.timestamp
                and self.data == other.data
                and self.nonce == other.nonce
                and self.hash == other.hash):
            return True
        return False

    def __str__(self):
        return json.dumps(self.to_dict())


if __name__ == '__main__':
    print(Block().genesis())